package com.zhss.demo.zk;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMultiLock;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.ArrayList;
import java.util.List;

public class ZkLockHelp {
    static CuratorFramework client = null;

    static {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        client = CuratorFrameworkFactory.newClient(
                "192.168.56.102:2181,192.168.56.102:2182,192.168.56.102:2183",
                retryPolicy);
        client.start();
    }

    public static CuratorFramework getClient() {
        if (client == null) {
            synchronized (ZkLockHelp.class) {
                RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
                client = CuratorFrameworkFactory.newClient(
                        "192.168.56.102:2181,192.168.56.102:2182,192.168.56.102:2183",
                        retryPolicy);
                client.start();
            }
        }
        return client;
    }

    public static void shutdown() {
        if (client != null) {
            client.close();
        }
        System.err.println("shutdown now .");
    }

    /**
     * 获取互斥锁
     */
    public static InterProcessMutex getReentrnLock(String name) throws Exception {
        return new InterProcessMutex(getClient(), buildPath(name));
    }

    /**
     * 获取读写锁
     */
    public static InterProcessReadWriteLock getReadWriteLock(String name) throws Exception {
        return new InterProcessReadWriteLock(getClient(), buildPath(name));
    }

    /**
     * 获取不可重入互斥锁
     */
    public static InterProcessSemaphoreMutex getSemaphoreLock(String name) throws Exception {
        return new InterProcessSemaphoreMutex(getClient(), buildPath(name));
    }

    /**
     * 获取多锁  集合锁
     */
    public static InterProcessMultiLock getMutilLock(List<String> names) throws Exception {
        return new InterProcessMultiLock(getClient(), mutilPath(names));
    }

    private static List<String> mutilPath(List<String> names) {
        List<String> paths = new ArrayList<>();
        for (String name : names) {
            paths.add(buildPath(name));
        }
        return paths;
    }


    private static String buildPath(String name) {
        StringBuilder path = new StringBuilder();
        String[] roots = new String[]{"cjm_lock", "mylock"};
        for (String str : roots) {
            if (str.startsWith("/")) {
                path.append("/");
            }
            path.append("/").append(str);
        }
        path.append("/").append(name);
        return path.toString();
    }
}
